import java.util.HashMap;

/*
 * @lc app=leetcode.cn id=208 lang=java
 *
 * [208] 实现 Trie (前缀树)
 */

// @lc code=start
class Trie {
    public class TrieNode{
        public int path; //表示当前节点所能链接到其他节点的个数（在删除操作中会用到）
        public boolean end; //表示以当前节点为结尾的单词的个数
        public HashMap<Character, TrieNode> next; //表示当前节点能链接到的所有节点
        public TrieNode(){
            path = 0;
            end = false;
            next = new HashMap<>();
        }
    }
    private TrieNode root;
    /** Initialize your data structure here. */
    public Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
        if(word == null || word.equals("")) return;
        TrieNode node = root;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            if(!node.next.containsKey(c)){
                node.next.put(c, new TrieNode());
            }
            node = node.next.get(c);
            node.path++;
        }
        node.end = true;
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        if(word == null || word.equals("")) return false;
        TrieNode node = root;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            if(!node.next.containsKey(c)){
                return false;
            }
            node = node.next.get(c);
        }
        return node.end;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
        if(prefix == null || prefix.equals("")) return false;
        TrieNode node = root;
        for (int i = 0; i < prefix.length(); i++) {
            char c = prefix.charAt(i);
            if(!node.next.containsKey(c)){
                return false;
            }
            node = node.next.get(c);
        }
        return true;
    }

    public void delete(String word){
        if(word == null || word.equals("")) return;
        TrieNode node = root;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            if(node.next.containsKey(c)){
                if(node.next.get(c).path == 0){
                    node.next.remove(c);
                }
                node.next.get(c).path--;
            }
            node = node.next.get(c);
        }
        node.end = false;
    }
}

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * boolean param_2 = obj.search(word);
 * boolean param_3 = obj.startsWith(prefix);
 */
// @lc code=end

